#pragma once

#include <iostream>
#include <string>
#include <cstdio>
#include <set>

const int line_size = 1024;

class Command
{
public:
	Command()
	{
		_white_list.insert("ls");
		_white_list.insert("pwd");
		_white_list.insert("ls -l");
		_white_list.insert("ll");
		_white_list.insert("touch");
		_white_list.insert("who");
		_white_list.insert("whoami");
	}

	bool SafeCheck(const std::string& cmdstr)
	{
		auto iter = _white_list.find(cmdstr);
		return iter == _white_list.end() ? false : true;
	}

	// 给你一个命令字符串，"ls -l",让你执行，执行完把结果返回
	std::string Execute(std::string cmdstr)
	{
		if(!SafeCheck(cmdstr))  // 检测是否在白名单
			return std::string(cmdstr + "不支持");

		// 1.pipe
		// 2.fork + dup2(pipe[1],1) + exec*，执行结果返回父进程,pipe[0]
		// 3.return

		FILE *fp = ::popen(cmdstr.c_str(), "r");
		if (fp == nullptr)
		{
			return std::string("Failed");
		}

		char buffer[line_size];
		std::string result;
		while (1)
		{
			char *ret = ::fgets(buffer, sizeof(buffer), fp);
			if (ret == nullptr)
				break;
			result += ret;
		}

		pclose(fp);

		return result.empty() ? std::string("Done") : result;
	}

private:
	std::set<std::string> _white_list;
};